package com.itheima.health.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 拦截器
 */
@Component
@Slf4j
public class SessionInterceptor implements HandlerInterceptor {
    // 存放需要权限拦截的路径
    Map<String,String> loginAuthUrlMap = new HashMap<>();
    // 定义登录后，需要授权访问的URI，（没在此map的，登录即可访问）
     {
        // 未在列表中的，默认用户登录就可以访问
        // 在列表中的，需要判断当前用户是否有匹配的权限，才可以访问
        // 1.比如以下URI，需要用户有CHECKITEM_DELETE权限
        loginAuthUrlMap.put("/checkitem/delete","CHECKITEM_DELETE");
        loginAuthUrlMap.put("/checkgroup/delete","CHECKITEM_DELETE");
        loginAuthUrlMap.put("/setmeal/delete","CHECKITEM_DELETE");
        // 2.比如访问report下的所有内容，需要用户有REPORT_VIEW权限，才可以访问
        loginAuthUrlMap.put("/report/**","REPORT_VIEW");
    }

    // 匹配通配符
    private AntPathMatcher pathMatcher = new AntPathMatcher();


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 判断是否登录过
        User user = (User) request.getSession().getAttribute("user");
        if (user == null) { // 没有登录
            Result result = new Result(false, "请先登录");
            String resultStr = JSONObject.toJSONString(result);
            response.getOutputStream().write(resultStr.getBytes());
            return false;
        }
        // 已登录

        // 获取用户的请求地址
        String requestURI = request.getRequestURI();

        // 判断本次请求的地址是否需要权限，如果需要则返回访问当前地址的权限，如果不需要权限返回null
        String permission = getPermission(requestURI);
        if (permission == null) {
            // 本次请求不需要权限 放行
            return true;
        }

        // 需要权限逻辑
        // 判断本次请求地址当前用户是否有权限访问
        // 1.获取当前用户的权限
        Set<String> permissionKeywords = user.getPermissions();
        if (permissionKeywords == null || permissionKeywords.size() == 0) {
            // 没有查到当前用户权限(无权访问)
            Result result = new Result(false, "对不起，你没有权限请求");
            String resultStr = JSONObject.toJSONString(result);
            response.getOutputStream().write(resultStr.getBytes());
            return false;
        }

        // 2.判断当前用户是否有此权限请求本路径
        for (String permissionKeyword : permissionKeywords) {
            if (permission.equals(permissionKeyword)) {
                // 相等，代表有权限
                return true;
            }
        }

        // 3.当前用户权限不够情况
        Result result = new Result(false, "对不起，你没有权限请求");
        String resultStr = JSONObject.toJSONString(result);
        response.getOutputStream().write(resultStr.getBytes());
        return false;
    }


    /**
     * 判断访问当前地址知否需要权限
     * @param url 访问的地址
     * @return String： 需要权限，返回访问当前地址所需要的权限，不需要权限返回null
     */
    private String getPermission(String url) {
        // 遍历需要权限的地址
        for (String permissionUrl : loginAuthUrlMap.keySet()) {
            // 判断当前地址是否在需要权限的地址中
            if (pathMatcher.match(permissionUrl, url)) {
                // 需要权限
                return loginAuthUrlMap.get(permissionUrl);
            }
        }
        return null;
    }


}
